package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.exception.BusinessException;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.core.enums.UserBindEnum;
import com.atguigu.srb.core.hfb.FormHelper;
import com.atguigu.srb.core.hfb.HfbConst;
import com.atguigu.srb.core.hfb.RequestHelper;
import com.atguigu.srb.core.mapper.UserBindMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.pojo.entity.UserBind;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.vo.UserBindVO;
import com.atguigu.srb.core.service.UserBindService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

/**
 * 用户绑卡服务实现类
 * 负责处理用户银行卡绑定相关业务逻辑
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class UserBindServiceImpl extends ServiceImpl<UserBindMapper, UserBind> implements UserBindService {

    private final UserInfoMapper userInfoMapper;

    /**
     * 提交用户绑卡信息到汇付宝平台
     *
     * @param userBindVO 用户提交的绑卡信息
     * @param userId     用户ID
     * @return 自动提交的表单HTML字符串，用于跳转到汇付宝绑卡页面
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String commitBindUser(UserBindVO userBindVO, Long userId) {

        // 检查身份证号码是否已被其他用户绑定
        LambdaQueryWrapper<UserBind> queryWrapper = new LambdaQueryWrapper<UserBind>().eq(UserBind::getIdCard, userBindVO.getIdCard()).ne(UserBind::getUserId, userId);

        Integer count = baseMapper.selectCount(queryWrapper);
        Assert.isTrue(count == 0, ResponseEnum.USER_BIND_IDCARD_EXIST_ERROR);

        // 查询用户当前绑定状态
        queryWrapper = new LambdaQueryWrapper<UserBind>().eq(UserBind::getUserId, userId);
        UserBind userBind = baseMapper.selectOne(queryWrapper);

        // 创建或更新绑定记录
        if (userBind == null) {
            // 创建新的绑定记录
            userBind = new UserBind();
            userBind.setUserId(userId);
            userBind.setIdCard(userBindVO.getIdCard());
            userBind.setName(userBindVO.getName());
            userBind.setBankType(userBindVO.getBankType());
            userBind.setBankNo(userBindVO.getBankNo());
            userBind.setMobile(userBindVO.getMobile());
            userBind.setStatus(UserBindEnum.NO_BIND.getStatus());
            baseMapper.insert(userBind);
        } else {
            // 更新已有绑定记录
            userBind.setIdCard(userBindVO.getIdCard());
            userBind.setName(userBindVO.getName());
            userBind.setBankType(userBindVO.getBankType());
            userBind.setBankNo(userBindVO.getBankNo());
            userBind.setMobile(userBindVO.getMobile());
            baseMapper.updateById(userBind);
        }

        // 构建提交到汇付宝的参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("agentId", HfbConst.AGENT_ID);
        paramMap.put("agentUserId", userId);
        paramMap.put("idCard", userBindVO.getIdCard());
        paramMap.put("personalName", userBindVO.getName());
        paramMap.put("bankType", userBindVO.getBankType());
        paramMap.put("bankNo", userBindVO.getBankNo());
        paramMap.put("mobile", userBindVO.getMobile());
        paramMap.put("returnUrl", HfbConst.USERBIND_RETURN_URL);
        paramMap.put("notifyUrl", HfbConst.USERBIND_NOTIFY_URL);
        paramMap.put("timestamp", System.currentTimeMillis());

        // 生成签名
        String sign = RequestHelper.getSign(paramMap);
        paramMap.put("sign", sign);

        // 生成自动提交表单
        return FormHelper.buildForm(HfbConst.USERBIND_URL, paramMap);
    }

    /**
     * 账户绑定异步回调
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void notify(Map<String, Object> paramMap) {
        log.info("收到账户绑定回调，参数: {}", paramMap);

        // 参数校验
        String bindCode = (String) paramMap.get("bindCode");
        String agentUserId = (String) paramMap.get("agentUserId");

        if (bindCode == null || agentUserId == null) {
            log.error("回调参数缺失，bindCode: {}, agentUserId: {}", bindCode, agentUserId);
            throw new BusinessException("回调参数缺失");
        }

        // 查询用户绑定记录
        UserBind userBind = baseMapper.selectOne(new LambdaQueryWrapper<UserBind>().eq(UserBind::getUserId, agentUserId));

        if (userBind == null) {
            log.error("用户绑定记录不存在，userId: {}", agentUserId);
            throw new BusinessException("用户绑定记录不存在");
        }

        // 查询用户信息
        UserInfo userInfo = userInfoMapper.selectById(agentUserId);

        if (userInfo == null) {
            log.error("用户信息不存在，userId: {}", agentUserId);
            throw new BusinessException("用户信息不存在");
        }

        try {
            // 更新用户绑定表
            userBind.setBindCode(bindCode);
            userBind.setStatus(UserBindEnum.BIND_OK.getStatus());
            baseMapper.updateById(userBind);

            // 更新用户表
            userInfo.setBindCode(bindCode);
            userInfo.setName(userBind.getName());
            userInfo.setIdCard(userBind.getIdCard());
            userInfo.setBindStatus(UserBindEnum.BIND_OK.getStatus());
            userInfoMapper.updateById(userInfo);

            log.info("账户绑定成功，userId: {}", agentUserId);
        } catch (Exception e) {
            log.error("账户绑定更新失败，userId: {}", agentUserId, e);
            throw e;
        }
    }

    /**
     * 获取投资人的绑定协议号
     */
    @Override
    public String getBindCodeByUserId(Long investUserId) {
        LambdaQueryWrapper<UserBind> wrapper = new LambdaQueryWrapper<UserBind>().eq(UserBind::getUserId, investUserId);
        UserBind userBind = baseMapper.selectOne(wrapper);
        return userBind.getBindCode();
    }

}